package com.yiruantong.common.core.utils;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.servlet.JakartaServletUtil;
import cn.hutool.http.HttpStatus;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.util.LinkedCaseInsensitiveMap;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * 客户端工具类
 *
 * @author rattan
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ServletUtils extends JakartaServletUtil {

  /**
   * 获取String参数
   */
  public static String getParameter(String name) {
    return getRequest().getParameter(name);
  }

  /**
   * 获取String参数
   */
  public static String getParameter(String name, String defaultValue) {
    return Convert.toStr(getRequest().getParameter(name), defaultValue);
  }

  /**
   * 获取Integer参数
   */
  public static Integer getParameterToInt(String name) {
    return Convert.toInt(getRequest().getParameter(name));
  }

  /**
   * 获取Integer参数
   */
  public static Integer getParameterToInt(String name, Integer defaultValue) {
    return Convert.toInt(getRequest().getParameter(name), defaultValue);
  }

  /**
   * 获取Boolean参数
   */
  public static Boolean getParameterToBool(String name) {
    return Convert.toBool(getRequest().getParameter(name));
  }

  /**
   * 获取Boolean参数
   */
  public static Boolean getParameterToBool(String name, Boolean defaultValue) {
    return Convert.toBool(getRequest().getParameter(name), defaultValue);
  }

  /**
   * 获得所有请求参数
   *
   * @param request 请求对象{@link ServletRequest}
   * @return Map
   */
  public static Map<String, String[]> getParams(ServletRequest request) {
    final Map<String, String[]> map = request.getParameterMap();
    return Collections.unmodifiableMap(map);
  }

  /**
   * 获得所有请求参数
   *
   * @param request 请求对象{@link ServletRequest}
   * @return Map
   */
  public static Map<String, String> getParamMap(ServletRequest request) {
    Map<String, String> params = new HashMap<>();
    for (Map.Entry<String, String[]> entry : getParams(request).entrySet()) {
      params.put(entry.getKey(), StringUtils.join(entry.getValue(), StringUtils.SEPARATOR_COMMA));
    }
    return params;
  }

  /**
   * 获取request
   */
  public static HttpServletRequest getRequest() {
    try {
      return getRequestAttributes().getRequest();
    } catch (Exception e) {
      return null;
    }
  }

  /**
   * 获取response
   */
  public static HttpServletResponse getResponse() {
    try {
      return getRequestAttributes().getResponse();
    } catch (Exception e) {
      return null;
    }
  }

  /**
   * 获取session
   */
  public static HttpSession getSession() {
    return getRequest().getSession();
  }

  public static ServletRequestAttributes getRequestAttributes() {
    try {
      RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
      return (ServletRequestAttributes) attributes;
    } catch (Exception e) {
      return null;
    }
  }

  public static String getHeader(String name) {
    HttpServletRequest request = getRequest();
    if (ObjectUtil.isNull(request)) {
      return null;
    }

    String value = request.getHeader(name);
    if (StringUtils.isEmpty(value)) {
      return StringUtils.EMPTY;
    }
    return urlDecode(value);
  }

  public static String getHeader(HttpServletRequest request, String name) {
    String value = request.getHeader(name);
    if (StringUtils.isEmpty(value)) {
      return StringUtils.EMPTY;
    }
    return urlDecode(value);
  }

  public static Map<String, String> getHeaders(HttpServletRequest request) {
    Map<String, String> map = new LinkedCaseInsensitiveMap<>();
    Enumeration<String> enumeration = request.getHeaderNames();
    if (enumeration != null) {
      while (enumeration.hasMoreElements()) {
        String key = enumeration.nextElement();
        String value = request.getHeader(key);
        map.put(key, value);
      }
    }
    return map;
  }

  /**
   * 将字符串渲染到客户端
   *
   * @param response 渲染对象
   * @param string   待渲染的字符串
   */
  public static void renderString(HttpServletResponse response, String string) {
    try {
      response.setStatus(HttpStatus.HTTP_OK);
      response.setContentType(MediaType.APPLICATION_JSON_VALUE);
      response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
      response.getWriter().print(string);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  /**
   * 是否是Ajax异步请求
   *
   * @param request
   */
  public static boolean isAjaxRequest(HttpServletRequest request) {

    String accept = request.getHeader("accept");
    if (accept != null && accept.contains(MediaType.APPLICATION_JSON_VALUE)) {
      return true;
    }

    String xRequestedWith = request.getHeader("X-Requested-With");
    if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) {
      return true;
    }

    String uri = request.getRequestURI();
    if (StringUtils.equalsAnyIgnoreCase(uri, ".json", ".xml")) {
      return true;
    }

    String ajax = request.getParameter("__ajax");
    return StringUtils.equalsAnyIgnoreCase(ajax, "json", "xml");
  }

  public static String getClientIP() {
    return getClientIP(getRequest());
  }

  /**
   * 内容编码
   *
   * @param str 内容
   * @return 编码后的内容
   */
  public static String urlEncode(String str) {
    return URLEncoder.encode(str, StandardCharsets.UTF_8);
  }

  /**
   * 内容解码
   *
   * @param str 内容
   * @return 解码后的内容
   */
  public static String urlDecode(String str) {
    return URLDecoder.decode(str, StandardCharsets.UTF_8);
  }

  /**
   * 根据当前访问获取唯一身份标识码
   *
   * @return uuid码
   */
  public static String getUniqueId() {
    HttpServletRequest request = getRequest();
    // 尝试从X-Forwarded-For头获取IP地址
    String forwardedFor = request.getHeader("X-Forwarded-For");
    String ip = (forwardedFor != null ? forwardedFor : "") + request.getRemoteAddr();

    // 获取User-Agent
    String userAgent = request.getHeader("User-Agent");

    // 使用IP地址和User-Agent生成唯一标识码
    String uniqueId = ip + userAgent;

    // 生成唯一标识码的hash值
    return String.valueOf(uniqueId.hashCode()); // 或者 uniqueIdUUID
  }

}
